﻿using System;
using System.Linq;
using UnityEngine;

namespace MassiveBattle.Manager
{
	/// <summary>
	/// 보스전 기본 클래스.
	/// </summary>
	public class BaseBossManager : BaseManager
	{
		public override bool IsRaid
		{
			get { return true; }
		}

		protected override void InitPlayerPosition(GameObject member, int line, int pos, ref EArea area)
		{
			var positionTransform = formationPositionRoot.Find("Player").OfType<Transform>().FirstOrDefault(data => data.name.StartsWith(string.Format("{0}_{1:00}", line + 1, pos + 1)));

			if (positionTransform.name.EndsWith("L"))
				area = EArea.LEFT;
			else if (positionTransform.name.EndsWith("M"))
				area = EArea.MIDDLE;
			else if (positionTransform.name.EndsWith("R"))
				area = EArea.RIGHT;

			member.transform.position = positionTransform.position;
		}

		protected override void InitEnemy()
		{
			var sideData = DataList[ESide.ENEMY];
			var raidData = UserData.Instance.raidBossStartData;

			var member = GameObject.Find("I'm Bossssssssssssssss") ?? Instantiate(Resources.Load("Prefab/Battle/Character/" + GameData.Inst.ModelDefineDic[GameData.Inst.GetBossData(raidData.raidBossId).ToList()[0].modelID])) as GameObject;

			member.name = "I'm Bossssssssssssssss";
			member.SetActive(true);
			member.transform.position = formationPositionRoot.Find("Enemy").position;

			var controllerType = Type.GetType("MassiveBattle.Controller.Boss.BossController_" + raidData.raidBossId) ?? typeof(Controller.Boss.BaseBossController);
			var controller = new GameObject("Controller", controllerType).GetComponent<Controller.Boss.BaseBossController>();

			sideData.CharacterList.Add(controller);

			controller.SetManager(this);
			controller.ModelGameObject = member;
			controller.EventPhaseChange += OnPhaseChange;
			controller.EventDie += ShowBossDieCutscene;
			controller.Init(raidData.raidBossId, raidData.lv, raidData.hp, ESide.ENEMY, ELine.FIRST, 0);

			sideData.InitHealthPoint();
			sideData.UpdateHealthPoint();

			UI.NameEnemy = controller.Name;
			UI.SetPortraitEnemy(sideData.CharacterList[0]);
		}

		public override void StartBattle()
		{
			int seed = 100;

			RaidBossStartModel raidDataCur;

			if (UserData.Instance.raidBossStartData == null)
				UserData.Instance.raidBossStartData = raidDataCur = new RaidBossStartModel();
			else
				raidDataCur = UserData.Instance.raidBossStartData;

			if (raidDataCur.raidBossId <= 0 || cheat.isBossIdForce)
				raidDataCur.raidBossId = cheat.bossId;
			if (raidDataCur.lv <= 0)
				raidDataCur.lv = 1;
			if (raidDataCur.seed <= 0)
				raidDataCur.seed = seed;

			var raidData = GameData.Inst.GetBossData(raidDataCur.raidBossId).FirstOrDefault();

			if (raidDataCur.hp <= 0)
				raidDataCur.hp = raidData.baseHP;

			seed = raidDataCur.seed;

			Init(seed);
		}

		protected override void RequestBattleEnd(bool isWin)
		{
			int hpDec = UserData.Instance.raidBossStartData.hp - DataList[ESide.ENEMY].HealthPointCur;

			//NetworkManager.Instance.C2S_END_RAIDBOSS_BATTLE(OnBattleEndResponse, isWin ? 1 : 2, hpDec, new[] { 1 });
			NetworkManager.Instance.C2S_GSTAR_END_RAIDBOSS_BATTLE(WorldSceneManager_GStar.sentResearchAreaId, hpDec, isWin ? 1 : 2, OnBattleEndResponse);
		}

		/// <summary>
		/// 페이즈가 바뀌었을 때.
		/// </summary>
		private void OnPhaseChange(int phase, int typeFlag)
		{
			this.typeFlag = typeFlag;
			Phase = phase;

			StopTake();

			PauseBattle();

			var controller = DataList[ESide.ENEMY].CharacterList[0];

			controller.FsmMain.Transit(EStateMain.enterstage);
			controller.EventTakeEnd += OnPhaseChangeEnd;
		}

		/// <summary>
		/// 페이즈 변경이 끝났을 때.
		/// </summary>
		private void OnPhaseChangeEnd(Controller.BaseController source)
		{
			source.EventTakeEnd -= OnPhaseChangeEnd;

			PlayNextTake();

			ResumeBattle();

			if (Phase == 2)
				UI.ShowNofiticationEffect(TextController.GetStringWithId(string.Format("raidNotice{0}Phase2", source.Id)));

			foreach (var character in DataList[ESide.PLAYER].CharacterList.Where(data => data.IsAlive))
			{
				if (!IsAttackTypeValid(character.Stat.atkType.Get(Monitor)))
					character.SetState(EState.STUN);
				else
					character.SetState();
			}
		}

		private void ShowBossDieCutscene()
		{
			StopTake();

			var controller = DataList[ESide.ENEMY].CharacterList[0];

			controller.FsmMain.Transit(EStateMain.die);
			controller.EventTakeEnd += OnBossDieCutsceneEnd;
		}

		private void OnBossDieCutsceneEnd(Controller.BaseController source)
		{
			source.EventTakeEnd -= OnBossDieCutsceneEnd;

			EndBattle(true);
		}

	}
}
